///<reference path='../../typings/tsd.d.ts'/>
import HookedWeb3Provider = require("hooked-web3-provider");
import Web3 = require('web3');
import lightwallet = require("eth-lightwallet");
import Config from "../config/Config";
const Tx = require("ethereumjs-tx");
import LogUtil from "./LogUtil";

/**
 * Web3工具类
 */
export default class Web3Util {
    static nonce = 1;

    /**
     * 根据keystore生成Web3对象
     * @param any keystore eth-lightwallet的keystore对象，或被序列化的keystore字符串
     * @return web3实例化对象
     */
    public static generateWeb3ByKeystore(_keystore, pwDerivedKey: Uint8Array) {
        let keystore = null;
        if (typeof _keystore === "string") {
            keystore = lightwallet.keystore.deserialize(_keystore);
        } else {
            keystore = _keystore;
        }
        let web3 = new Web3();
        web3.setProvider(new HookedWeb3Provider({
            host: Config.WEB3_HOST,
            transaction_signer: keystore
        }));

        //keystore.setPwDerivedKey(pwDerivedKey);//保存密钥，避免需要出现重复输入密码的情况
        // keystore.generateNewAddress(pwDerivedKey,1);
        // let addresses:string[] = keystore.getAddresses();
        //web3.eth.defaultAccount = "0x"+addresses[0];//默认使用第一个地址作为账号
        //console.log("defaultAccount:"+web3.eth.defaultAccount);
        return web3;
    }

    /**
     * 发送交易
     * 
     */
    public static sendTransaction(web3, accountAddress:string, privateKey:Buffer, targetAddress:string, amount, payload, callback) {
        let gasPriceHex = web3.toHex(web3.eth.gasPrice);
        let gasLimitHex = web3.toHex(300000);
        let nonce = web3.eth.getTransactionCount(accountAddress, 'pending');
        let nonceHex = web3.toHex(nonce);
        let rawTx = {
            nonce: nonceHex,
            gasPrice: gasPriceHex,
            gasLimit: gasLimitHex,
            to: targetAddress,
            from: accountAddress,
            value: web3.toHex(amount),
            data: undefined
        };
        
        if (payload) {
            rawTx.data = payload;
        }
        // console.log(rawTx);
        let tx = new Tx(rawTx);

        try {
            tx.sign(privateKey);
        } catch (e) {
            LogUtil.info(e);
            return false;
        }
        let serializedTx = tx.serialize();
        let serializedTxHex = "0x"+serializedTx.toString('hex');
        // console.log('Sign Transaction: ' + serializedTxHex);
        // console.log("Send Transaction");
        if(typeof callback==="function"){
            return web3.eth.sendRawTransaction(serializedTxHex,callback);
        }else{
            return web3.eth.sendRawTransaction(serializedTxHex);
        }
    }
}